<?php
/**
 * SQL_Maker
 *
 * PHP version 5
 *
 * LICENSE:
 *
 * Copyright (c) 2012, sink <sink.cup@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *    * The names of the authors may not be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * @category sql maker
 * @package  SQL_Maker
 * @author   sink <sink.cup@gmail.com>
 * @license  http://opensource.org/licenses/bsd-license.php New BSD License
 * @version  SVN: $Id: Request2.php 324936 2012-04-07 07:49:03Z avb $
 * @link     http://pear.php.net/package/SQL_Maker/
 */

$this_dir = dirname(__FILE__) . '/';
require $this_dir . 'Maker/Base.php';
require $this_dir . 'Maker/Exception.php';
require $this_dir . 'Maker/Mysql.php';
require $this_dir . 'Maker/Pgsql.php';
class SQL_Maker
{
    private $syntex;

    /**
     * if user mysql, conf like array(
     *      'api' => 'pdo', //or 'mysqli', dafault 'pdo'
     *      'sql_mode' => '', // or 'ansi', default ''
     *      'table_name' => '', // not null
     * )
     * if user pgsql, conf like array(
     *      'api' => 'pdo', //or 'pgsql', dafault 'pdo'
     *      'schema_name' => 'public', //default 'public'
     *      'table_name' => '', // not null
     * )
     *
     * @param string    $db_product     eg. mysql,postgresql
     * @param mixed     $db_connection  eg. PDO OBJ, mysqli OBJ, pg_connect    
     * @param array     $conf
     */
    public function __construct($db_product, $db_connection, array $conf)
    {
        switch ($db_product) {
            case 'mysql' :
                $this->syntex = new SQL_Maker_Mysql($db_connection, $conf);
                break;
            case 'pgsql' :
                $this->syntex = new SQL_Maker_Pgsql($db_connection, $conf);
                break;
            default :
                throw new SQL_Maker_Exception();
                break;
        }
    }

    public function delete($where='')
    {
        return 'DELETE FROM ' . $this->syntex->quoteTableName() . $this->syntex->implodeToWhere($where);
    }
    
    public function insertRow($data)
    {
        return 'INSERT INTO ' . $this->syntex->quoteTableName() . ' (' . $this->syntex->implodeToColumn(array_keys($data)) . ') VALUES ' . $this->syntex->implodeToRowValues(array_values($data));
    }

    public function insertRows($data) {
        $data_for_query = array();
        $columns = array_keys($data[0]);
        foreach($data as $one_row) {
            $data_for_query[] = array_values($one_row);
        }
        return 'INSERT INTO ' . $this->syntex->quoteTableName() . ' (' . $this->syntex->implodeToColumn(array_values($columns)) . ') VALUES ' . $this->syntex->implodeToRowsValues($data_for_query);
    }

    /**
     * 因为经常会查询SELECT * FROM article where id=?，这时候只传第一个参数即可。
     * 所以where放第一位。
     */
    public function select($where='', $column='*', $limit_start=0, $limit_size='', $group_by='', $order_by='')
    {
        $sql = 'SELECT ' . $this->syntex->implodeToColumn($column) . ' FROM ' . $this->syntex->quoteTableName() . $this->syntex->implodeToWhere($where);
        if(!empty($group_by)) {
            $sql .= ' GROUP BY ' . $this->syntex->implodeToColumn($group_by);
        }
        if(!empty($order_by)) {
            if(strpos(trim($order_by), ' ') !== false) {
                $tmp = explode(' ', trim($order_by));
                $sql .= ' ORDER BY ' . $this->syntex->quoteColumn($tmp[0]) . ' ' . strtoupper($tmp[1]);
            } else {
                $sql .= ' ORDER BY ' . $this->syntex->quoteColumn($order_by);
            }
        }
        if(!empty($limit_size)) {
            $sql .= $this->syntex->limit($limit_start, $limit_size);
        }
        return $sql;
    }

    public function selectCount($where='', $column='*')
    {
        if($column!='*') {
            $sql = 'SELECT COUNT(' . $this->syntex->quoteColumn() . ') as count';
        }   
        else {
            $sql = 'SELECT COUNT(*) as count';
        }   
        //$sql .= empty($group_by) ? '' : ',' . $group_by;
        $sql .= ' FROM ' . $this->syntex->quoteTableName();
        $sql .= $this->syntex->implodeToWhere($where);
        //$sql = !empty($group_by) ? $sql . ' GROUP BY ' . $group_by : $sql;
        return $sql;
    }
    
    public function update($data, $where='')
    {
        return 'UPDATE ' . $this->syntex->quoteTableName() . ' SET ' . $this->syntex->implodeToUpdate($data) . $this->syntex->implodeToWhere($where);
    }
}
?>
